#ifndef GROUP_H_
#define GROUP_H_

#include "priority_queue.h"
#include "user.h"
#include "recipe.h"
#include <string>
#include <vector>
#include <memory>
using std::string;
using std::shared_ptr;
using std::vector;

namespace mtm {
class Group {
	static const int BjarneBirthMonth = 12;
	const string name;
	//last appointmented leader
	shared_ptr<PowerUser> leader;
	vector<shared_ptr<Recipe>> recipes;
	vector<shared_ptr<User>> users;
	/*
	 * appoint a new leader
	 * find the most donating user in the group, and turn it
	 * to a group leader
	 * return value: a pointer to PowerUser, which represent the
	 * 		new leader
	 * throws:
	 * ForeverAloneException, if there is not another user in group
	 */
	shared_ptr<PowerUser> appointNewLeader();
public:
	/*
	 * Group's constructor
	 * arguments:
	 * name - the group's name
	 * leader - a pointer to the opener of the group
	 */
	Group(const string& name, const shared_ptr<PowerUser>& leader);
	//get the group's name
	const string& getName() const {
		return name;
	}
	/*
	 * remove old recipes
	 * arguments:
	 * k - the maximum recipes number in the group after cleaning
	 */
	void cleanMemory(unsigned int k);
	/*
	 * get the activity level of the group
	 */
	int activityLevel() const;
	/*
	 * print the group's name, surrounded by parentheses
	 * arguments:
	 * os - the stream to print to
	 * group - the group to print
	 * return value: os
	 */
	friend ostream& operator<<(ostream& os, const Group& group);
	//get the group's name
	const string& getName() {
		return name;
	}
	//helper function for User::joinNewGroup
	void joinRequest(const shared_ptr<User>& user);

	//helper function for User::leaveGroup
	void leaveRequest(const shared_ptr<User>& user);

	//helper function for User::postRecipe
	void postRecipe(const shared_ptr<Recipe>& recipe);
	/*
	 * get pointer to a recipe from the group
	 * arguments:
	 * recipeName - the name of the recipe
	 * return value - a pointer to the recipe
	 * throws:
	 * NoSuchRecipeInGroupException, if there is not such recipe in the group
	 */
	shared_ptr<Recipe> getRecipe(const string& recipeName);
	friend class PowerUser;
};

}

#endif /* GROUP_H_ */
